/*
实验7-5 社交网络图中结点的“重要性”计算
分数 30
作者 DS课程组
单位 浙江大学

在社交网络中，个人或单位（结点）之间通过某些关系（边）联系起来。他们受到这些关系的影响，这种影响可以理解为网络中相互连接的结点之间蔓延的一种相互作用，可以增强也可以减弱。而结点根据其所处的位置不同，其在网络中体现的重要性也不尽相同。

“紧密度中心性”是用来衡量一个结点到达其它结点的“快慢”的指标，即一个有较高中心性的结点比有较低中心性的结点能够更快地（平均意义下）到达网络中的其它结点，因而在该网络的传播过程中有更重要的价值。在有 n 个结点的网络中，结点 vi​ 的“紧密度中心性” Cc(vi​) 数学上定义为 vi​ 到其余所有结点 vj​ (j=i) 的最短距离 d(vi​,vj​) 的平均值的倒数：

<src img="../imgs/sy7-5.png">

对于非连通图，所有结点的紧密度中心性都是 0。

给定一个无权的无向图以及其中的一组结点，计算这组结点中每个结点的紧密度中心性。
输入格式:

输入第一行给出两个正整数 n 和 m，其中 n（≤10^3）是图中结点个数，顺便假设结点从 1 到 n 编号；m（≤10^4）是边的条数。随后的 m 行中，每行给出一条边的信息，即该边连接的两个结点编号，中间用空格分隔。最后一行给出需要计算紧密度中心性的这组结点的个数 k（≤100）以及 k 个结点编号，用空格分隔。
输出格式:

按照 Cc(i)=x.xx 的格式输出 k 个给定结点的紧密度中心性，每个输出占一行，结果保留到小数点后 2 位。
输入样例:

9 14
1 2
1 3
1 4
2 3
3 4
4 5
4 6
5 6
5 7
5 8
6 7
6 8
7 8
7 9
3 3 4 9

输出样例:

Cc(3)=0.47
Cc(4)=0.62
Cc(9)=0.35
*/

#include "../base/MGraph.cpp"

#include <iostream>

using namespace std;

// 定义权重的最大值
#define MaxWeight 0x7FFF
// 无路径
#define Connectionless -1

bool floyed(MGraph<int, int> &graph, int **weight, int ** path) {
    int n = graph.get_num_vertex() + 1;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            weight[i][j] = graph.get_edge(i, j);
            path[i][j] = Connectionless;
        }
    }

    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (weight[i][j] > weight[i][k] + weight[k][j]) {
                    if (i == j && weight[i][j] < 0) {
                        return false; // 发现负值圈
                    }
                    weight[i][j] = weight[i][k] + weight[k][j];
                    path[i][j] = k;
                }
            }
        }
    }
    return true;
}

int main() {
    int n, m;
    cin >> n >> m;
    MGraph<int, int> graph(n, MaxWeight, false);
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        graph.add_edge(u, v, 1);
    }

    int **weight = new int*[n + 1];
    int **path = new int*[n + 1];
    for (int i = 0; i <= n; i++) {
        weight[i] = new int[n + 1];
        path[i] = new int[n + 1];
    }

    floyed(graph, weight, path);

    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
        int node;
        cin >> node;
        double sum = 0;
        for (int j = 1; j <= n; j++) {
            if (j != node) {
                sum += weight[node][j];
            }
        }
        double c = (n - 1) / sum;
        printf("Cc(%d)=%.2f\n", node, c);
    }

    // free memory
    for (int i = 0; i <= n; i++) {
        delete[] weight[i];
        delete[] path[i];
    }
    delete[] weight;
    delete[] path;

    return 0;
}